home *** CD-ROM | disk | FTP | other *** search
/ Pascal Super Library / Pascal Super Library (CW International)(1997).bin / LIBRARY / DSUTIL12 / ASC2BIN / ASC2BIN.PAS < prev   
Pascal/Delphi Source File  |  1993-10-28  |  25KB  |  754 lines

  1. {-----------------------------------------------------------------------}
  2. { PROJECT        NON-PROFIT HIGH QUALITY PROFESSIONAL SOFTWARE,  }
  3. {            AVAILABLE FOR ALL WORLD                }
  4. { LIBRARY        SYSTEM UTILITIES                                }
  5. { MODULE        ASC_TO_BIN_CONVERTER                            }
  6. { FILE NAME        ASC2BIN.PAS                    }
  7. { PURPOSE        Convert the ASCII file to the binary file.    }
  8. { VERSION        1.10                        }
  9. { DATE            28-Oct-93                    }
  10. { DESIGN        Dmitry Stefankov                }
  11. { IMPLEMENTATION    Dmitry Stefankov                 }
  12. { COMPANY        Freelance Software Engineer            }
  13. { ADDRESS        Isakowskogo str, 4-2-30                }
  14. {            Moscow, 123181                    }
  15. {            USSR                        }
  16. {            Tel. 007 (095) 944-6304                }
  17. { COPYRIGHT NOTICE    Copyright (C) 1987-1993, Dmitry Stefankov    }
  18. { RESTRICTED RIGHTS    AVAILABLE ONLY FOR FREE DISTRIBUTION,           }
  19. {            NOT FOR COMMERCIAL PURPOSE            }
  20. { COMPUTER        IBM PC or compatible                }
  21. { OPERATING SYSTEM    MS/PC-DOS Version 3.30 or higher        }
  22. { COMPILER        Turbo Pascal Version 6.0            }
  23. {                       (Borland International Inc.) or compatible      }
  24. { ASSEMBLY LANGUAGE    Microsoft MASM 5.10 or compatible               }
  25. { LINKER        Turbo Pascal internal                           }
  26. { ARGUMENTS        <infile>     -   input  stream                  }
  27. {                       <outfile>    -   output stream                  }
  28. {                       <base>       -   representation number base     }
  29. {                       <type>       -   type of binary number          }
  30. {                       <numcount>   -   # of extracted numbers/line    }
  31. { RETURN        None                        }
  32. { REQUIRES        None                                            }
  33. { NATURAL LANGUAGE      English Language                                 }
  34. { SPECIAL        None                        }
  35. { DESCRIPTION        1. Read from input stream                       }
  36. {                       2. Convert ASCII to binary representation       }
  37. {                       3. Write converted output stream                }
  38. { REVISION HISTORY    Dima Stefankov (DS)                }
  39. {               1.00   15-May-93  DS  initilal release        }
  40. {                       1.01   19-May-93  DS  some style corrections    }
  41. {            1.02   18-Oct-93  DS  some style updates    }
  42. {            1.10   28-Oct-93  DS  some minor changes    }
  43. {-----------------------------------------------------------------------}
  44.  
  45.  
  46. {*======================= PROGRAM HEADER PART ==========================*}
  47.  
  48. PROGRAM   AsciiFormatFileToBinaryFormatFile;
  49.  
  50.  
  51. {*** other modules ***}
  52. {*USES;*}
  53.  
  54.  
  55. {** switches for compilation **}
  56. {$S-}                 {*  stack checking     *}
  57. {$R-}                    {*  range checking     *}
  58. {$M 16384,65536,65536}   {*  memory allocation  *}
  59.  
  60.  
  61. {*========================== CONSTANTS PART ============================*}
  62.  
  63. CONST
  64.      asPurpose                  =       'AscBinFile Converter';
  65.      asVersion                  =       '1.10';
  66.      asAuthor                   =       'Dima Stefankov';
  67.      asCopyright                =       'Copyright (c) 1987, 1993';
  68.      asProgramPrompt            =       'Asc2bin: ';
  69.      asProgram            =    'Asc2bin';
  70.      asProgramU            =    'ASC2BIN';
  71.  
  72.    { exit codes }
  73.      errTerminateOK             =     0;
  74.      errBadParmsNumber          =     1;
  75.      errSourceNotFound          =     2;
  76.      errDestDontWrite           =     3;
  77.      errSameNames               =     4;
  78.      errSrcOpenFailed           =     6;
  79.      errDestCreateFailed        =     7;
  80.      errBadBase                 =     8;
  81.      errBadType                 =     9;
  82.      errBadBytesValue           =     10;
  83.  
  84.    { miscellaneous }
  85.      achDosExtMark              =     '.';
  86.      asBlankStr                 =     '';
  87.      asSpaces5                  =     '     ';
  88.      asInDefExt                 =     'asc';
  89.      asOutDefExt                =     'bin';
  90.      aPercent100                =     100;
  91.  
  92.    { ASCII characters }
  93.      achNULL                    =     #0;
  94.      achHTAB                    =     #9;
  95.      achCR                      =     #13;
  96.      achBlank                   =     ' ';
  97.  
  98.      achYes                     =     'Y';
  99.      achNo                      =     'N';
  100.  
  101.    { number base conversion }
  102.      aOctalRadix                =     8;
  103.      aDecimalRadix              =     10;
  104.      aHexRadix                  =     16;
  105.      achHexPrefix               =     '$';
  106.  
  107.    { default values }
  108.      aDefBaseNumber             =     16;
  109.      aDefBytesPerBinaryNumber   =     1;
  110.      aBinaryNumberBytes1        =     1;
  111.      aBinaryNumberBytes2        =     2;
  112.      aBinaryNumberBytes3        =     3;
  113.      aBinaryNumberBytes4        =     4;
  114.      aMaxBytesPerBinaryNumber   =     4;
  115.      aDefNumbersPerLine         =     16;
  116.      aMaxNumbersPerLine         =     32;
  117.  
  118.    { buffers size }
  119.      aMaxTextBufSize            =       32768;          { 32K    }
  120.      aMaxOutBufSize             =       65520;          { 64K-16 }
  121.  
  122.  
  123.  
  124. {*==================== TYPE DECLARATIONS PART ==========================*}
  125.  
  126. TYPE
  127.     STR2        =       STRING[2];
  128.     STR4        =       STRING[4];
  129.  
  130.  
  131. {*====================== TYPED CONSTANTS PART ==========================*}
  132.  
  133. CONST
  134.  
  135.     setOctalChars            :   SET  OF  System.Char  =  ['0'..'7'];
  136.     setDecimalChars          :   SET  OF  System.Char  =  ['0'..'9'];
  137.     setHexChars              :   SET  OF  System.Char  =  ['0'..'9','A'..'F','a'..'f'];
  138.     setAvailRadix            :   SET  OF  System.Byte  =  [aOctalRadix,aDecimalRadix,aHexRadix];
  139.     setUnusedLeadChars       :   SET  OF  System.Char  =  [achHTAB,achBlank];
  140.  
  141.     gliReadBytesCount        :   System.Longint   =   0;
  142.     gdwBufOfs                :   System.Word      =   0;
  143.  
  144.     gadbNumberBase           :   System.Byte      =   aDefBaseNumber;
  145.     gadbBytesPerBinaryNumber :   System.Byte      =   aDefBytesPerBinaryNumber;
  146.     gdaNumbersPerLine        :   System.Byte      =   aDefNumbersPerLine;
  147.  
  148.  
  149. {*=========================== VARIABLES PART ===========================*}
  150.  
  151. VAR
  152.    gfInputStream        :       System.Text;
  153.    gfInputStreamRec     :       FILE  ABSOLUTE  gfInputStream;
  154.    gsInFileName         :       STRING[80];
  155.  
  156.    gfOutputStream       :       FILE;
  157.    gsOutFileName        :       STRING[80];
  158.  
  159.    gliFileSize          :       System.Longint;
  160.    glpOutBuf            :       System.Pointer;
  161.    giErrorCode          :       System.Integer;
  162.    gsTempInput          :       STRING;
  163.  
  164.    gdbLargeInBuf        :       ARRAY[0..aMaxTextBufSize-1] OF System.Char;
  165.  
  166.  
  167. {*=========================== FUNCTIONAL PART ==========================*}
  168.  
  169. FUNCTION  _fnbFileExist(VAR fStruc : FILE; sFileName : STRING) : System.Boolean;
  170. {* Check that file exits. *}
  171. VAR
  172.   bResult  :  System.Boolean;
  173.  
  174. BEGIN
  175.   {** attempt to open the file **}
  176.     System.Assign(fStruc,sFileName);
  177.     {$I-}
  178.     System.Reset(fStruc);
  179.     {$I+}
  180.  
  181.   {** copy the result of last I/O operation **}
  182.     bResult := (System.IOResult = 0);
  183.  
  184.     IF (bResult)
  185.       THEN  System.Close(fStruc);
  186.     {if-then}
  187.  
  188.   _fnbFileExist := bResult;
  189. END; { _fnbFileExist }
  190.  
  191.  
  192. FUNCTION  _fnsForceFileNameExt(sFileName, sDefExt : STRING) : STRING;
  193. {* Add extension for filename if not present. *}
  194. BEGIN
  195.    IF (System.Pos(achDosExtMark,sFileName) = 0)
  196.      THEN sFileName := sFileName + achDosExtMark + sDefExt;
  197.    {if-then}
  198.   _fnsForceFileNameExt := sFileName;
  199. END;
  200. { _fnsForceFileNameExt }
  201.  
  202.  
  203. FUNCTION   _fnchGetFirstChar(sInput : STRING) : System.Char;
  204. {* Returns a first char from string. *}
  205. VAR
  206.   chTemp  :  System.Char;
  207.  
  208. BEGIN
  209.    IF (System.Length(sInput) <> 0)
  210.      THEN  chTemp := sInput[1]
  211.      ELSE  chTemp := achNULL;
  212.    {if-then-else}
  213.   _fnchGetFirstChar := chTemp;
  214. END;
  215. { _fnchGetFirstChar }
  216.  
  217.  
  218.  
  219. FUNCTION  _fnsUpcaseStr(sInput : STRING) : STRING;
  220. {* Make all uppercase. *}
  221. VAR
  222.   dbIndex  :  System.BYTE;
  223.   dbCount  :  System.BYTE;
  224.  
  225. BEGIN
  226.   dbCount := System.Length(sInput);
  227.  
  228.   FOR dbIndex :=  1  TO  dbCount DO
  229.       sInput[dbIndex] := System.Upcase(sInput[dbIndex]);
  230.   {for-to-do}
  231.  
  232.    _fnsUpcaseStr := sInput;
  233. END; { _fnsUpcaseStr }
  234.  
  235.  
  236. FUNCTION  _fndbHexCharToBin(chIn: System.Char) : System.Byte; assembler;
  237. {* Converts hexadecimal char to decimal digit. *}
  238. asm
  239.         mov   al, chIn       { AL = chIn }
  240.         sub   al,'0'         { AL <- AL - '0' }
  241.  
  242.         cmp   al,9           { test for digit }
  243.         jbe   @Done
  244.  
  245.         and   al,11011111b   { make uppercase }
  246.         sub   al,'A'-'9'-1   { AL = 'A'..'F' }
  247.  
  248.       @Done:
  249.                         { AL = function result }
  250. END;
  251.   {asm-end}
  252. { HexCharToDec }
  253.  
  254.  
  255. FUNCTION  _fnliOctalStrToBin(sOctalInput : STRING; VAR iErrCode : System.Integer) : System.Longint;
  256. {* Converts octal string to binary number. *}
  257. VAR
  258.   ddNumber               :       System.Longint;
  259.   dbStrIndex, dbStrLen   :       System.Byte;
  260.  
  261. BEGIN
  262.   iErrCode   := 0;
  263.   ddNumber   := 0;
  264.   dbStrIndex := 1;
  265.   dbStrLen   := System.Length(sOctalInput);
  266.  
  267.   WHILE (iErrCode = 0) and (dbStrLen > 0) DO
  268.   BEGIN
  269.     IF  (sOctalInput[dbStrIndex] IN setOctalChars)
  270.     THEN  BEGIN
  271.                ddNumber := ddNumber * aOctalRadix + System.Byte(sOctalInput[dbStrIndex])-System.Byte('0');
  272.                System.Inc(dbStrIndex);
  273.                System.Dec(dbStrLen);
  274.           END
  275.     ELSE
  276.         iErrCode  := -1;
  277.     {if-then-else}
  278.   END;
  279.   {while-do}
  280.  
  281.   _fnliOctalStrToBin := ddNumber;
  282. END;  { _fnliOctalStrToBin }
  283.  
  284.  
  285. FUNCTION  _fnliDecimalStrToBin(sDecimalInput : STRING; VAR iErrCode : System.Integer) : System.Longint;
  286. {* Converts decimal string to binary number. *}
  287. VAR
  288.   ddNumber               :       System.Longint;
  289.   dbStrIndex, dbStrLen   :       System.Byte;
  290.  
  291. BEGIN
  292.   iErrCode   := 0;
  293.   ddNumber   := 0;
  294.   dbStrIndex := 1;
  295.   dbStrLen   := System.Length(sDecimalInput);
  296.  
  297.   WHILE (iErrCode = 0) and (dbStrLen > 0) DO
  298.   BEGIN
  299.     IF  (sDecimalInput[dbStrIndex] IN setDecimalChars)
  300.     THEN  BEGIN
  301.                ddNumber := ddNumber * aDecimalRadix + System.Byte(sDecimalInput[dbStrIndex])-System.Byte('0');
  302.                System.Inc(dbStrIndex);
  303.                System.Dec(dbStrLen);
  304.           END
  305.     ELSE
  306.         iErrCode  := -1;
  307.     {if-then-else}
  308.   END;
  309.   {while-do}
  310.  
  311.   _fnliDecimalStrToBin := ddNumber;
  312. END;  { _fnliDecimalStrToBin }
  313.  
  314.  
  315. FUNCTION  _fnliHexStrToBin(sHexInput : STRING; VAR iErrCode : System.Integer) : System.Longint;
  316. {* Converts hexadecimal string to binary number. *}
  317. VAR
  318.   ddNumber               :       System.Longint;
  319.   dbStrIndex, dbStrLen   :       System.Byte;
  320.  
  321. BEGIN
  322.   iErrCode   := 0;
  323.   ddNumber   := 0;
  324.   dbStrIndex := 1;
  325.   dbStrLen   := System.Length(sHexInput);
  326.  
  327.   WHILE (iErrCode = 0) and (dbStrLen > 0) DO
  328.   BEGIN
  329.     IF  (sHexInput[dbStrIndex] IN setHexChars)
  330.     THEN  BEGIN
  331.                ddNumber := ddNumber * aHexRadix + _fndbHexCharToBin(sHexInput[dbStrIndex]);
  332.                System.Inc(dbStrIndex);
  333.                System.Dec(dbStrLen);
  334.           END
  335.     ELSE
  336.         iErrCode  := -1;
  337.     {if-then-else}
  338.   END;
  339.   {while-do}
  340.  
  341.   _fnliHexStrToBin := ddNumber;
  342. END;  { _fnliHexStrToBin }
  343.  
  344.  
  345. FUNCTION  _fnddGetNum(sInput : STRING;VAR iErrorCode : System.Integer)  :  System.Longint;
  346. {* Reads a numeric string and returns a double word *}
  347. VAR
  348.   ddTemp      :   System.Longint;
  349.  
  350. BEGIN
  351.   IF  (sInput[1] <> achHexPrefix)
  352.      THEN  System.Val(sInput,ddTemp,iErrorCode)
  353.      ELSE  ddTemp := _fnliHexStrToBin(Copy(sInput,2,System.Length(sInput)-1),iErrorCode);
  354.   {if-then-else}
  355.   _fnddGetNum := ddTemp;
  356. END;
  357. { _fnddGetNum }
  358.  
  359.  
  360. FUNCTION  _fndwGetNum(sInput : STRING;VAR iErrorCode : System.Integer)  :  System.Word;
  361. {* Reads a numeric string and returns a word *}
  362. BEGIN
  363.  _fndwGetNum := (_fnddGetNum(sInput,iErrorCode) AND $000FFFF);
  364. END;
  365. { _fndwGetNum }
  366.  
  367.  
  368. FUNCTION  _fndbGetNum(sInput : STRING;VAR iErrorCode : System.Integer)  :  System.Byte;
  369. {* Reads a numeric string and returns a byte *}
  370. BEGIN
  371.  _fndbGetNum := (_fnddGetNum(sInput,iErrorCode) AND $000000FF);
  372. END;
  373. { _fndbGetNum }
  374.  
  375.  
  376. FUNCTION  _fnsRemoveLeadChars(sInput : STRING) : STRING;
  377. {* Remove all occurrences of leading char from left side. *}
  378. BEGIN
  379.    WHILE ((sInput <> asBlankStr) AND (sInput[1] IN setUnusedLeadChars))
  380.    DO  System.Delete(sInput,1,1);
  381.    {while-do}
  382.    _fnsRemoveLeadChars := sInput;
  383. END; { _fnsRemoveLeadChars }
  384.  
  385.  
  386. FUNCTION  _fnsNumToStr2(dwNum : System.Word) : STR2;
  387. {* Convert a numeric value to its string representation. *}
  388. VAR
  389.   sTemp2 : STR2;
  390.  
  391. BEGIN
  392.    System.Str(dwNum:2,sTemp2);
  393.    _fnsNumToStr2 := sTemp2;
  394. END;
  395. { _fnsNumToStr2 }
  396.  
  397.  
  398. {*=========================== PROCEDURAL PART ==========================*}
  399.  
  400. PROCEDURE    _CopyrightDisplay;
  401. {* Outputs the copyright notice. *}
  402. BEGIN
  403.      System.WriteLn(asPurpose+
  404.                     '  Version '+
  405.                     asVersion+
  406.                     ', '+
  407.                     asCopyright+
  408.                     '  '+
  409.                     asAuthor);
  410. END;  { _CopyrightDisplay }
  411.  
  412.  
  413. PROCEDURE  _PutByteToOutFile(dbNextChar : System.Byte);
  414. {* Buffered writing to output stream. *}
  415. BEGIN
  416.   IF  (gdwBufOfs >= aMaxOutBufSize)
  417.     THEN  BEGIN
  418.          System.BlockWrite(gfOutputStream,
  419.                            System.Mem[System.Seg(glpOutBuf^):System.Ofs(glpOutBuf^)],
  420.                            aMaxOutBufSize);
  421.          gdwBufOfs := 0;
  422.           END;
  423.   {if-then}
  424.   System.Mem[System.Seg(glpOutBuf^):(System.Ofs(glpOutBuf^)+gdwBufOfs)] := dbNextChar;
  425.   System.Inc(gdwBufOfs);
  426. END;
  427. {  _PutByteToOutFile }
  428.  
  429.  
  430.  
  431. PROCEDURE  _ProcessLine(sInput : STRING);
  432. {* Process one line. *}
  433. VAR
  434.   sCurNumStr      :  STRING;
  435.   ddTempNumber    :  System.LongInt;
  436.   iErrorCode      :  System.Integer;
  437.   dwByteOffset    :  System.Word;
  438.   dbNumbersCount  :  System.Byte;
  439.   dbWriteCount    :  System.Byte;
  440.   chCurSym        :  System.Char;
  441.   bMatchSym       :  System.Boolean;
  442.  
  443. FUNCTION  _fnchGetCurSymbol(VAR sInput : STRING) : System.Char;
  444. {* Returns a first char from a string
  445.    with the following removing of it from string. *}
  446. VAR
  447.   chTemp  :  System.Char;
  448. BEGIN
  449.   chTemp := _fnchGetFirstChar(sInput);
  450.   IF (chTemp <> achNULL)
  451.     THEN  System.Delete(sInput,1,1);
  452.   _fnchGetCurSymbol := chTemp;
  453. END;
  454. { _fnchGetCurSymbol }
  455.  
  456. BEGIN
  457.   {* init an internal counter *}
  458.     dbNumbersCount := 0;
  459.     sInput := _fnsUpcaseStr(sInput);
  460.     sInput := _fnsRemoveLeadChars(sInput);
  461.  
  462.   {* scan a string until it is no empty or max. numbers count not reached *}
  463.     WHILE  ((sInput <> asBlankStr) AND
  464.             (dbNumbersCount < gdaNumbersPerLine))  DO
  465.     BEGIN
  466.       {* try to get the numeric substring, *}
  467.         sCurNumStr  := asBlankStr;
  468.  
  469.       {* one char look-ahead algorithm     *}
  470.       REPEAT
  471.         chCurSym  := _fnchGetCurSymbol(sInput);
  472.         bMatchSym := System.False;
  473.  
  474.         CASE  gadbNumberBase  OF
  475.                aOctalRadix    :  BEGIN
  476.                                    IF  (chCurSym IN setOctalChars)
  477.                                      THEN  BEGIN
  478.                                        sCurNumStr :=  sCurNumStr + chCurSym;
  479.                                        bMatchSym := System.True;
  480.                                            END;
  481.                                    {if-then}
  482.                                  END;
  483.                aDecimalRadix  :  BEGIN
  484.                                    IF  (chCurSym IN setDecimalChars)
  485.                                      THEN  BEGIN
  486.                                        sCurNumStr :=  sCurNumStr + chCurSym;
  487.                                        bMatchSym := System.True;
  488.                                            END;
  489.                                    {if-then}
  490.                                  END;
  491.                aHexRadix      :  BEGIN
  492.                                    IF  (chCurSym IN setHexChars)
  493.                                      THEN  BEGIN
  494.                                        sCurNumStr :=  sCurNumStr + chCurSym;
  495.                                        bMatchSym := System.True;
  496.                                            END;
  497.                                    {if-then}
  498.                                  END;
  499.         ELSE
  500.           {* reserved *}
  501.         END;
  502.         {case-of}
  503.  
  504.       UNTIL  ((sInput = asBlankStr) OR
  505.                 NOT(bMatchSym));
  506.       {repeat-until}
  507.  
  508.       {* make the number conversion if need *}
  509.       IF (sCurNumStr <> asBlankStr)
  510.         THEN  BEGIN
  511.            CASE  gadbNumberBase  OF
  512.                   aOctalRadix    :  BEGIN
  513.                       ddTempNumber := _fnliOctalStrToBin(sCurNumStr,iErrorCode);
  514.                                     END;
  515.                   aDecimalRadix  :  BEGIN
  516.                        ddTempNumber := _fnliDecimalStrToBin(sCurNumStr,iErrorCode);
  517.                                     END;
  518.                   aHexRadix      :  BEGIN
  519.                       ddTempNumber := _fnliHexStrToBin(sCurNumStr,iErrorCode);
  520.                                     END;
  521.            ELSE
  522.              {* reserved *}
  523.            END;
  524.            {case-of}
  525.  
  526.            IF (iErrorCode = 0)  THEN
  527.              BEGIN
  528.                  CASE  gadbBytesPerBinaryNumber  OF
  529.                      aBinaryNumberBytes1  : dbWriteCount := 1;
  530.                      aBinaryNumberBytes2  : dbWriteCount := 2;
  531.                      aBinaryNumberBytes3  : dbWriteCount := 3;
  532.                      aBinaryNumberBytes4  : dbWriteCount := 4;
  533.                  ELSE
  534.                      dbWriteCount := 0;
  535.                  END;
  536.                  IF (dbWriteCount <> 0)
  537.                    THEN  BEGIN
  538.                       FOR  dwByteOffset := 0  TO  dbWriteCount-1  DO
  539.                       BEGIN
  540.                         _PutByteToOutFile(Mem[Seg(ddTempNumber):(Ofs(ddTempNumber)+dwByteOffset)])
  541.                       END;
  542.                       {for-to-do}
  543.                       {**  Alternative **}
  544.                       {**System.BlockWrite(gfOutputStream,ddTempNumber,dbWriteCount);**}
  545.                       {**  Alternative **}
  546.                       System.Inc(dbNumbersCount);
  547.                          END;
  548.                  {if-then}
  549.              END;
  550.            {if-then}
  551.               END;
  552.       {if-then}
  553.  
  554.       {* prepare a string for the next parsing *}
  555.         sInput := _fnsRemoveLeadChars(sInput);
  556.     END;
  557.     {while-do}
  558.  
  559. END;
  560. { _ProcessLine }
  561.  
  562.  
  563. {*============================== MAIN PART =============================*}
  564.  
  565. BEGIN
  566.   _CopyrightDisplay;
  567.  
  568.      IF (System.ParamCount < 2) THEN
  569.      BEGIN
  570.           System.WriteLn(asProgramPrompt+'  help screen for you.');
  571.           System.WriteLn('Usage: infile outfile [base [type [numcount]]]');
  572.           System.WriteLn(' infile   - source filename                   (default extension='+asInDefExt+')');
  573.           System.WriteLn(' outfile  - destination filename              (default extension='+asOutDefExt+')');
  574.           System.WriteLn(' base     - representation number base        (default=',aDefBaseNumber,
  575.                          ', available=',aOctalRadix,',',aDecimalRadix,',',aHexRadix,')');
  576.           System.WriteLn(' type     - bytes number per binary entity    (default=',aDefBytesPerBinaryNumber,
  577.                          ', max=',aMaxBytesPerBinaryNumber,')');
  578.           System.WriteLn(' numcount - numbers count extracted from line (default=',aDefNumbersPerLine,
  579.                          ', max=',aMaxNumbersPerLine,')');
  580.           System.WriteLn('  Numbers may be decimals, or hexadecimals (first symbol is ''$'' for hex.).');
  581.           System.Halt(errBadParmsNumber);
  582.      END;
  583.      {if-then}
  584.  
  585.  
  586.   {** copy the parameters from command line **}
  587.     gsInFileName  := _fnsUpcaseStr(System.ParamStr(1));
  588.     gsInFileName := _fnsForceFileNameExt(gsInFileName,asInDefExt);
  589.  
  590.     gsOutFileName := _fnsUpcaseStr(System.ParamStr(2));
  591.     gsOutFileName := _fnsForceFileNameExt(gsOutFileName,asOutDefExt);
  592.  
  593.  
  594.   {* may be same names? *}
  595.     IF (gsInFileName = gsOutFileName)  THEN
  596.     BEGIN
  597.       System.WriteLn(asProgramPrompt+'  Unable to use same file as input and as output');
  598.       System.Halt(errSameNames);
  599.     END;
  600.     {if-then}
  601.  
  602.  
  603.   {** source file exists? **}
  604.     IF  NOT(_fnbFileExist(gfInputStreamRec,gsInFileName)) THEN
  605.     BEGIN
  606.       System.WriteLn(asProgramPrompt+' Unable to open file '+gsInFileName);
  607.       System.Halt(errSourceNotFound);
  608.     END;
  609.     {if-then}
  610.  
  611.  
  612.   {** destination file present? **}
  613.   IF (_fnbFileExist(gfOutputStream,gsOutFileName)) THEN
  614.   BEGIN
  615.     System.Write(asProgramPrompt+' Output file '+gsOutFileName+
  616.                  ' already exists. Overwrite? (n/y): ');
  617.     System.ReadLn(gsTempInput);
  618.     IF (System.UpCase(_fnchGetFirstChar(gsTempInput)) <> achYes)
  619.       THEN  System.Halt(errDestDontWrite);
  620.     {if-then}
  621.   END;
  622.   {if-then}
  623.  
  624.  
  625.   {** read the following parameter = number base **}
  626.     IF  (System.ParamCount >= 3) THEN
  627.     BEGIN
  628.       gadbNumberBase := _fndbGetNum(System.ParamStr(3),giErrorCode);
  629.       IF  ((giErrorCode <> 0) OR
  630.            (NOT(gadbNumberBase IN setAvailRadix)))
  631.       THEN
  632.           BEGIN
  633.             System.WriteLn(asProgramPrompt+'Invalid BASE parameter.');
  634.             System.Halt(errBadBase);
  635.           END;
  636.       {if-then}
  637.     END;
  638.     {if-then}
  639.  
  640.  
  641.   {** read the following parameter = binary type **}
  642.     IF  (System.ParamCount >= 4) THEN
  643.     BEGIN
  644.        gadbBytesPerBinaryNumber := _fndbGetNum(System.ParamStr(4),giErrorCode);
  645.        IF  ((giErrorCode <> 0) OR
  646.             (gadbBytesPerBinaryNumber > aMaxBytesPerBinaryNumber) OR
  647.             (gadbBytesPerBinaryNumber = 0))
  648.        THEN
  649.            BEGIN
  650.              System.WriteLn(asProgramPrompt+'Bad TYPE parameter.');
  651.              System.Halt(errBadType);
  652.            END;
  653.        {if-then}
  654.     END;
  655.     {if-then}
  656.  
  657.   {** read the following parameter = bytes switch **}
  658.     IF  (System.ParamCount >= 5) THEN
  659.     BEGIN
  660.          gdaNumbersPerLine := _fndbGetNum(System.ParamStr(5),giErrorCode);
  661.          IF ((giErrorCode <> 0) OR
  662.              (gdaNumbersPerLine = 0) OR
  663.              (gdaNumbersPerLine > aMaxNumbersPerLine))
  664.             THEN   BEGIN
  665.                System.WriteLn(asProgramPrompt+' Invalid value for NUMCOUNT switch.');
  666.                System.Halt(errBadBytesValue);
  667.                    END;
  668.          {if-then}
  669.     END;
  670.     {if-then}
  671.  
  672.  
  673.   {** open the source file **}
  674.     System.Assign(gfInputStreamRec,gsInFileName);
  675.     {$I-}
  676.     System.Reset(gfInputStreamRec,1);
  677.     {$I+}
  678.  
  679.     IF  (System.IoResult <> 0) THEN
  680.     BEGIN
  681.       System.Write(asProgramPrompt+' Unable to open '+gsInFileName);
  682.       System.Halt(errSrcOpenFailed);
  683.     END;
  684.     {if-then}
  685.  
  686.     gliFileSize := System.FileSize(gfInputStreamRec);
  687.     System.Close(gfInputStreamRec);
  688.  
  689.   {** open the source file **}
  690.     System.Assign(gfInputStream,gsInFileName);
  691.     System.SetTextBuf(gfInputStream,gdbLargeInBuf);
  692.     {$I-}
  693.     System.Reset(gfInputStream);
  694.     {$I+}
  695.  
  696.     IF  (System.IoResult <> 0) THEN
  697.     BEGIN
  698.       System.Write(asProgramPrompt+' Unable to open '+gsInFileName);
  699.       System.Halt(errSrcOpenFailed);
  700.     END;
  701.     {if-then}
  702.  
  703.  
  704.   {** create the destination file **}
  705.     System.GetMem(glpOutBuf,aMaxOutBufSize);
  706.     System.Assign(gfOutputStream,gsOutFileName);
  707.     {$I-}
  708.     System.Rewrite(gfOutputStream,1);
  709.     {$I+}
  710.  
  711.     IF  (System.IoResult <> 0) THEN
  712.     BEGIN
  713.       System.WriteLn(asProgramPrompt+' Unable to create '+gsOutFileName);
  714.       System.Halt(errDestCreateFailed);
  715.     END;
  716.     {if-then}
  717.  
  718.  
  719.  
  720.   {** main loop: read_buffer/write_to_text_file **}
  721.     WHILE (NOT(System.Eof(gfInputStream))) DO
  722.     BEGIN
  723.          System.ReadLn(gfInputStream,gsTempInput);
  724.          System.Inc(gliReadBytesCount,System.Length(gsTempInput)+2);
  725.          System.Write(achCR+asProgramPrompt+' Completed ('+
  726.                       _fnsNumToStr2(System.Word(gliReadBytesCount*aPercent100 DIV gliFileSize))+'%)');
  727.          _ProcessLine(gsTempInput);
  728.     END;
  729.     {while-do}
  730.  
  731.  
  732.   {* output '100%' message *}
  733.     System.WriteLn(achCR+asProgramPrompt+' Completed (',aPercent100,'%)');
  734.  
  735.   {* write a remainder in buffer to disk *}
  736.     IF  (gdwBufOfs <> 0)
  737.       THEN  System.BlockWrite(gfOutputStream,
  738.                               System.Mem[System.Seg(glpOutBuf^):System.Ofs(glpOutBuf^)],
  739.                               gdwBufOfs);
  740.     {if-then}
  741.  
  742.   {** close all files **}
  743.     System.Close(gfInputStream);
  744.     System.Close(gfOutputStream);
  745.  
  746.   {* free all memory on heap *}
  747.     System.FreeMem(glpOutBuf,aMaxOutBufSize);
  748.  
  749.   {** report all done **}
  750.     System.WriteLn(asProgramPrompt+' Done.');
  751.  
  752.   {* System.Halt(errTerminateOk); *}
  753. END.
  754.